package com.bxw.forum.service.impl;

import com.bxw.forum.common.AppResult;
import com.bxw.forum.common.ResultCode;
import com.bxw.forum.dao.UserMapper;
import com.bxw.forum.exception.ApplicationException;
import com.bxw.forum.model.User;
import com.bxw.forum.service.IUserService;
import com.bxw.forum.utils.MD5Utils;
import com.bxw.forum.utils.StringUtils;
import com.bxw.forum.utils.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;


@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;


    /**
     * 创建用户
     * @param user
     */
    @Override
    public void createNormalUser(User user) {
        //注册业务，从前端提交的表单到后端生成一个User实体类（username,password,nickname,salt）
        //salt在controller中生成
        //1，参数校验（username,password,nickname,salt）
        //错误抛出异常
        //2，通过用户名字去检查是否存在
        //存在抛出异常用户已存在
        //3，不存在择去创建
        //失败抛出异常


        if(user == null
                || StringUtils.isEmpty(user.getUsername())
                || StringUtils.isEmpty(user.getPassword())
                || StringUtils.isEmpty(user.getNickname())
                || StringUtils.isEmpty(user.getSalt())) {
            //日志打印
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));

        }

        User existUser = userMapper.selectByUserName(user.getUsername());

        if(existUser != null) {

            log.warn(ResultCode.FAILED_USER_EXISTS.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_EXISTS));
        }
        user.setGender((byte) 2);
        user.setIsAdmin((byte) 0);
        user.setState((byte) 0);
        user.setDeleteState((byte) 0);
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);

        int row = userMapper.insertSelective(user);

        if(row != 1) {
            log.warn(ResultCode.FAILED_CREATE.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_CREATE));
        }

        log.info(ResultCode.SUCCESS.toString());

    }

    /**
     * 根据用户名查询用户信息
     * @param username 用户名
     * @return
     */
    @Override
    public User selectByUserName(String username) {

        //1，数据校验
        //2，根据用户名查询是否已经存在

        if(StringUtils.isEmpty(username)) {

            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        User user = userMapper.selectByUserName(username);

        return user;
    }

    /**
     * 登录
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @Override
    public User login(String username, String password) {

        //1，数据校验
        //2，检查是否存在
        //3，判断密码

        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        User user = selectByUserName(username);

        if(user == null) {
            //打印日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            //抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN));
        }


        String encryptPassword = MD5Utils.md5Salt(password,user.getSalt());


        if(!encryptPassword.equalsIgnoreCase(user.getPassword())) {
            //打印日志
            log.warn(ResultCode.FAILED_LOGIN.toString());
            //抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN));
        }


        return user;

    }

    /**
     * 根据用户id查询用户信息
     * @param id 用户id
     * @return
     */
    @Override
    public User selectById(Long id) {

        if(id == null) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_FORBIDDEN));
        }

        User user = userMapper.selectByPrimaryKey(id);

        return user;
    }


    /**
     * 通过用户ID增加对应的文章数量
     * @param id 用户ID
     */
    @Override
    public void addOneArticleCountById(Long id) {

        if(id == null || id <= 0) {
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }

        User user = userMapper.selectByPrimaryKey(id);

        if(user == null || user.getDeleteState() != 0) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setArticleCount(user.getArticleCount() + 1);

        int row = userMapper.updateByPrimaryKeySelective(updateUser);

        if(row != 1) {
            log.warn(ResultCode.ERROR_SERVICES.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.ERROR_SERVICES));
        }

    }

    /**
     * 通过用户ID减少对应的文章数量
     * @param id 用户ID
     */
    @Override
    public void subOneArticleCountById(Long id) {

        if(id == null || id <= 0) {
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }

        User user = userMapper.selectByPrimaryKey(id);

        if(user == null || user.getDeleteState() != 0) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setArticleCount(user.getArticleCount() - 1);

        if(updateUser.getArticleCount() < 0) {
            updateUser.setArticleCount(0);
        }

        int row = userMapper.updateByPrimaryKeySelective(updateUser);

        if(row != 1) {
            log.warn(ResultCode.ERROR_SERVICES.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.ERROR_SERVICES));
        }
    }


    /**
     * 修改用户信息
     * @param user 用户对象
     */
    @Override
    public void modifyInfo(User user) {
        //非法校验
        //判断要修改的用户是否存在
        //设置标志位
        //新建要更新的用户
        //校验没一位要修改的数据(1,非空校验 2,是否与修改前相等 3,修改参数的合法性)
        //对标志位进行判断
        //动态更新
        if(user == null || user.getId() == null || user.getId() <= 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        User existUser = userMapper.selectByPrimaryKey(user.getId());

        if(existUser == null || existUser.getDeleteState() != 0) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        boolean check = false;

        User updateUser = new User();
        updateUser.setId(user.getId());

        //校验用户名
        if(!StringUtils.isEmpty(user.getUsername())
                && !user.getUsername().equals(existUser.getUsername())) {
            //注意，用传入的参数与已存在的数据比较
            //用户命名唯一性
            User checkUser = userMapper.selectByUserName(user.getUsername());

            if(checkUser != null) {
                log.warn(ResultCode.FAILED_USER_EXISTS.toString());

                throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_EXISTS));
            }
            updateUser.setUsername(user.getUsername());

            check = true;
        }

        //校验昵称
        if (!StringUtils.isEmpty(user.getNickname())
                && !user.getNickname().equals(existUser.getNickname())) {
            // 设置昵称
            updateUser.setNickname(user.getNickname());
            // 更新标志位
            check = true;
        }
        //校验性别
        if (user.getGender() != null && !user.getGender().equals(existUser.getGender())) {
            // 设置性别
            updateUser.setGender(user.getGender());
            // 合法性校验
            if (updateUser.getGender() > 2 || updateUser.getGender() < 0) {
                updateUser.setGender((byte) 2);
            }
            // 更新标志位
            check = true;
        }
        //校验邮箱
        if (!StringUtils.isEmpty(user.getEmail())
                && !user.getEmail().equals(existUser.getEmail())) {
            // 设置邮箱
            updateUser.setEmail(user.getEmail());
            // 更新标志位
            check = true;
        }
        //校验电话号码
        if (!StringUtils.isEmpty(user.getPhoneNum())
                && !user.getPhoneNum().equals(existUser.getPhoneNum())) {
            // 设置电话号码
            updateUser.setPhoneNum(user.getPhoneNum());
            // 更新标志位
            check = true;
        }
        //校验个人简介
        if (!StringUtils.isEmpty(user.getRemark())
                && !user.getRemark().equals(existUser.getRemark())) {
            // 设置电话号码
            updateUser.setRemark(user.getRemark());
            // 更新标志位
            check = true;
        }


        if(check == false) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        int row = userMapper.updateByPrimaryKeySelective(updateUser);

        if(row != 1) {
            log.warn(ResultCode.ERROR_SERVICES.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.ERROR_SERVICES));
        }

    }

    /**
     * 修改用户密码
     * @param id 用户ID
     * @param newPassword 新密码
     * @param oldPassword 旧密码
     */
    @Override
    public void modifyPassword(Long id, String newPassword, String oldPassword) {
        //非空校验数据
        //根据ID从DAO中查找user
        //对旧密码做判断
        //对新密码做MD5加盐处理
        //将新密码设置
        if(id == null || id <= 0 || StringUtils.isEmpty(newPassword) || StringUtils.isEmpty(oldPassword)) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        User existUser = userMapper.selectByPrimaryKey(id);

        if(existUser == null || existUser.getDeleteState() != 0) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        if(!existUser.getPassword().equalsIgnoreCase(MD5Utils.md5Salt(oldPassword,existUser.getSalt()))) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());

            throw new ApplicationException(AppResult.fail("原密码错误"));
        }

        String salt = UUIDUtils.UUID_32();
        String encryptPassword = MD5Utils.md5Salt(newPassword,salt);

        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setSalt(salt);
        updateUser.setPassword(encryptPassword);
        Date date = new Date();
        updateUser.setUpdateTime(date);

        int row = userMapper.updateByPrimaryKeySelective(updateUser);

        if(row != 1) {
            log.warn(ResultCode.ERROR_SERVICES.toString());

            throw new ApplicationException(AppResult.fail(ResultCode.ERROR_SERVICES));
        }
    }


}
